<template>
    <div class="china-map-container">
        <div class="map-header">
            <h4 class="map-title">{{ title }}</h4>
            <div class="map-controls">
                <el-button size="small" @click="resetMap">
                    <el-icon>
                        <Refresh />
                    </el-icon>
                    重置
                </el-button>
            </div>
        </div>

        <div class="map-content">
            <div class="map-wrapper">
                <div v-if="isLoading" class="loading-overlay">
                    <el-icon class="is-loading">
                        <Loading />
                    </el-icon>
                    <span>加载地图中...</span>
                </div>
                <div v-else-if="loadError" class="error-overlay">
                    <div class="error-content">
                        <el-icon class="error-icon">
                            <Loading />
                        </el-icon>
                        <span>地图资源加载失败</span>
                    </div>
                </div>
                <div v-else ref="chartRef" class="china-map"></div>
            </div>

            <!-- 图例 -->
            <div class="map-legend" v-if="showLegend">
                <div class="legend-title">数据范围</div>
                <div class="legend-items">
                    <div class="legend-item" v-for="(item, index) in legendData" :key="index">
                        <div class="legend-color" :style="{ backgroundColor: item.color }"></div>
                        <span class="legend-label">{{ item.label }}</span>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, computed, watch, nextTick } from 'vue'
import { Refresh, Loading } from '@element-plus/icons-vue'
import * as echarts from 'echarts'
import * as dataModule from '@/assets/data'

// 定义组件属性
interface Props {
    // 地图标题
    title?: string
    // 地图数据源文件路径（可选，不传则使用默认中国地图）
    geoJsonUrl?: string
    // 地图名称（用于注册）
    mapName?: string
    // 地图数据
    data: Array<{
        name: string
        value: number
        description?: string
        unit?: string
    }>
    // 地图高度
    height?: number
    // 是否显示图例
    showLegend?: boolean
    // 地图主题色
    theme?: 'blue' | 'green' | 'red' | 'purple'
    // 是否启用缩放
    enableZoom?: boolean
    // 是否显示省份边界
    showBoundary?: boolean
    // 是否显示省份标签
    showLabels?: boolean
}

// 设置默认值
const props = withDefaults(defineProps<Props>(), {
    title: '中国地图',
    geoJsonUrl: '',
    mapName: 'china',
    height: 500,
    showLegend: true,
    theme: 'blue',
    enableZoom: true,
    showBoundary: true,
    showLabels: true
})

// 响应式数据
const chartRef = ref<HTMLElement>()
let chartInstance: echarts.ECharts | null = null
const isLoading = ref(false)
const mapData = ref<any>(null)
const loadError = ref(false)

// 主题颜色配置
const themeColors = {
    blue: ['#F4F7FC', '#bbdefb', '#90caf9', '#64b5f6', '#42a5f5', '#2196f3', '#1e88e5', '#1976d2'],
    green: ['#e8f5e8', '#c8e6c9', '#a5d6a7', '#81c784', '#66bb6a', '#4caf50', '#43a047', '#388e3c'],
    red: ['#ffebee', '#ffcdd2', '#ef9a9a', '#e57373', '#ef5350', '#f44336', '#e53935', '#d32f2f'],
    purple: ['#f3e5f5', '#e1bee7', '#ce93d8', '#ba68c8', '#ab47bc', '#9c27b0', '#8e24aa', '#7b1fa2']
}

// 计算图例数据
const legendData = computed(() => {
    if (props.data.length === 0) return []

    const maxValue = Math.max(...props.data.map(item => item.value))
    const minValue = Math.min(...props.data.map(item => item.value))
    const step = (maxValue - minValue) / 7

    return themeColors[props.theme].map((color, index) => {
        const value = minValue + step * index
        return {
            color,
            label: `${value.toFixed(0)}${props.data[0]?.unit || ''}`
        }
    })
})

// 根据数值获取颜色
const getColorByValue = (value: number) => {
    if (props.data.length === 0) return themeColors[props.theme][0]

    const maxValue = Math.max(...props.data.map(item => item.value))
    const minValue = Math.min(...props.data.map(item => item.value))

    if (maxValue === minValue) return themeColors[props.theme][0]

    const ratio = (value - minValue) / (maxValue - minValue)
    const colorIndex = Math.floor(ratio * (themeColors[props.theme].length - 1))

    return themeColors[props.theme][colorIndex]
}

// 获取地图中心点
const getMapCenter = (geoData: any) => {
    if (geoData && geoData.center) {
        return geoData.center
    }
    return null
}

// 获取区域样式配置
const getFeatureStyle = (feature: any) => {
    if (feature.properties && feature.properties.style) {
        return feature.properties.style
    }
    return null
}

// 动态获取地图数据
const getMapDataByName = (mapName: string) => {
    // 将 mapName 转换为对应的数据导出名称
    // 例如: 'ahute' -> 'ahuteJson', 'anshanmaJson' -> 'anshanmaJson'
    const dataKey = mapName.endsWith('Json') ? mapName : `${mapName}Json`

    // 尝试从 dataModule 中获取对应的数据
    if (dataModule && typeof dataModule === 'object' && dataKey in dataModule) {
        return (dataModule as any)[dataKey]
    }

    // 如果没找到，尝试直接使用 mapName
    if (dataModule && typeof dataModule === 'object' && mapName in dataModule) {
        return (dataModule as any)[mapName]
    }

    return null
}

// 加载地图数据
const loadMapData = async () => {
    try {
        isLoading.value = true
        loadError.value = false

        if (props.geoJsonUrl) {
            // 从 URL 加载地图数据
            const response = await fetch(props.geoJsonUrl)
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`)
            }
            const geoData = await response.json()
            mapData.value = geoData
            echarts.registerMap(props.mapName, geoData)
        } else {
            // 从本地数据模块加载地图数据
            const geoData = getMapDataByName(props.mapName)

            if (geoData) {
                mapData.value = geoData
                echarts.registerMap(props.mapName, geoData)
            } else {
                throw new Error(`地图数据 "${props.mapName}" 不存在`)
            }
        }
    } catch (error) {
        console.error('加载地图数据失败:', error)
        loadError.value = true
        mapData.value = null
    } finally {
        isLoading.value = false
    }
}

// 初始化地图
const initChart = async () => {
    if (!chartRef.value) return

    // 先加载地图数据
    await loadMapData()

    // 如果加载失败，不初始化图表
    if (loadError.value || !mapData.value) {
        return
    }

    // 获取地图中心点
    const mapCenter = getMapCenter(mapData.value)

    // 根据地图类型设置默认中心点和缩放级别
    let defaultCenter: [number, number]
    let defaultZoom: number

    if (props.mapName === 'ahute') {
        defaultCenter = mapCenter
        defaultZoom = 1.2
    } else if (props.mapName === 'anshanmaJson') {
        defaultCenter = mapCenter
        defaultZoom = 1.2
    } else {
        defaultCenter = mapCenter
        defaultZoom = 1.2
    }

    // 创建图表实例
    chartInstance = echarts.init(chartRef.value)

    // 设置图表配置
    const option = {
        tooltip: {
            trigger: 'item',
            formatter: (params: any) => {
                // 查找对应的 GeoJSON feature 以获取样式配置
                const feature = mapData.value?.features?.find((f: any) => f.properties?.name === params.name)
                const styleConfig = feature ? getFeatureStyle(feature) : null

                // 根据样式配置禁用tooltip
                if (styleConfig?.hover === false) {
                    return null
                }

                const provinceName = params.name
                const data = props.data.find(item => item.name === provinceName)
                if (data) {
                    return `
                        <div style="padding: 8px;">
                            <div style="font-weight: bold; margin-bottom: 4px;">${data.name}</div>
                            <div style="color: #409eff; font-size: 14px;">${data.value}${data.unit || ''}</div>
                            ${data.description ? `<div style="color: #666; font-size: 12px; margin-top: 4px;">${data.description}</div>` : ''}
                        </div>
                    `
                }
                return `<div style="padding: 8px;">${params.name}</div>`
            }
        },
        series: [
            {
                name: props.title,
                type: 'map',
                map: props.mapName,
                roam: props.enableZoom,
                zoom: defaultZoom,
                center: defaultCenter,
                label: {
                    show: props.showLabels,
                    fontSize: 10,
                    color: '#333'
                },
                itemStyle: {
                    borderColor: props.showBoundary ? '#666' : 'transparent',
                    borderWidth: props.showBoundary ? 1 : 0,
                    areaColor: '#F4F7FC'
                },
                emphasis: {
                    label: {
                        show: true,
                        color: '#000',
                        fontSize: 12
                    },
                    itemStyle: {
                        areaColor: '#78DFFC'
                    }
                },
                select: {
                    disabled: true
                },
                data: props.data ? props.data.map(item => {
                    // 查找对应的 GeoJSON feature 以获取样式配置
                    const feature = mapData.value?.features?.find((f: any) => f.properties?.name === item.name)
                    const styleConfig = feature ? getFeatureStyle(feature) : null

                    return {
                        name: item.name,
                        value: item.value,
                        itemStyle: {
                            // 优先使用 GeoJSON 中的样式配置，否则使用默认逻辑
                            areaColor: styleConfig?.fill || getColorByValue(item.value),
                            borderColor: styleConfig?.stroke || (props.showBoundary ? '#666' : 'transparent'),
                            borderWidth: styleConfig?.strokeWidth || (props.showBoundary ? 1 : 0)
                        },
                        // 根据样式配置禁用hover效果
                        emphasis: styleConfig?.hover === false ? {
                            disabled: true
                        } : undefined
                    }
                }) : []
            }
        ]
    }

    chartInstance.setOption(option)
}

// 重置地图
const resetMap = () => {
    if (chartInstance) {
        chartInstance.dispatchAction({
            type: 'restore'
        })
    }
}

// 自适应窗口大小
const resizeChart = () => {
    if (chartInstance) {
        chartInstance.resize()
    }
}

// 监听数据变化
watch(() => props.data, () => {
    if (chartInstance && props.data && !loadError.value) {
        const newData = props.data.map(item => {
            // 查找对应的 GeoJSON feature 以获取样式配置
            const feature = mapData.value?.features?.find((f: any) => f.properties?.name === item.name)
            const styleConfig = feature ? getFeatureStyle(feature) : null

            return {
                name: item.name,
                value: item.value,
                itemStyle: {
                    // 优先使用 GeoJSON 中的样式配置，否则使用默认逻辑
                    areaColor: styleConfig?.fill || getColorByValue(item.value),
                    borderColor: styleConfig?.stroke || (props.showBoundary ? '#666' : 'transparent'),
                    borderWidth: styleConfig?.strokeWidth || (props.showBoundary ? 1 : 0)
                },
                // 根据样式配置禁用hover效果
                emphasis: styleConfig?.hover === false ? {
                    disabled: true
                } : undefined
            }
        })

        chartInstance.setOption({
            series: [{
                data: newData
            }]
        })
    }
}, { deep: true })

// 监听主题变化
watch(() => props.theme, () => {
    if (chartInstance && props.data && !loadError.value) {
        const newData = props.data.map(item => {
            // 查找对应的 GeoJSON feature 以获取样式配置
            const feature = mapData.value?.features?.find((f: any) => f.properties?.name === item.name)
            const styleConfig = feature ? getFeatureStyle(feature) : null

            return {
                name: item.name,
                value: item.value,
                itemStyle: {
                    // 优先使用 GeoJSON 中的样式配置，否则使用默认逻辑
                    areaColor: styleConfig?.fill || getColorByValue(item.value),
                    borderColor: styleConfig?.stroke || (props.showBoundary ? '#666' : 'transparent'),
                    borderWidth: styleConfig?.strokeWidth || (props.showBoundary ? 1 : 0)
                },
                // 根据样式配置禁用hover效果
                emphasis: styleConfig?.hover === false ? {
                    disabled: true
                } : undefined
            }
        })

        chartInstance.setOption({
            series: [{
                data: newData
            }]
        })
    }
})

// 监听 showLabels 变化
watch(() => props.showLabels, (newVal) => {
    if (chartInstance) {
        chartInstance.setOption({
            series: [{
                label: {
                    show: newVal
                }
            }]
        })
    }
})

// 监听地图数据源变化
watch(() => props.geoJsonUrl, async () => {
    if (chartInstance) {
        await loadMapData()
        initChart()
    }
})

// 生命周期
onMounted(() => {
    nextTick(async () => {
        await initChart()
        // 监听窗口大小变化
        window.addEventListener('resize', resizeChart)
    })
})

onBeforeUnmount(() => {
    if (chartInstance) {
        chartInstance.dispose()
    }
    window.removeEventListener('resize', resizeChart)
})
</script>

<style scoped>
.china-map-container {
    background: #fff;
    border-radius: 8px;
    border: 1px solid #e9ecef;
    overflow: hidden;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.map-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 16px 20px;
    background: #f8f9fa;
    border-bottom: 1px solid #e9ecef;
}

.map-title {
    margin: 0;
    font-size: 16px;
    font-weight: 600;
    color: #333;
}

.map-controls {
    display: flex;
    gap: 8px;
}

.map-content {
    position: relative;
    display: flex;
}

.map-wrapper {
    flex: 1;
    padding: 20px;
    position: relative;
}

.china-map {
    width: 100%;
    height: v-bind(height + 'px');
}

.loading-overlay {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.8);
    z-index: 10;
    gap: 8px;
    color: #666;
    font-size: 14px;
}

.error-overlay {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.9);
    z-index: 10;
}

.error-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    color: #f56c6c;
    font-size: 14px;
}

.error-icon {
    font-size: 24px;
    color: #f56c6c;
}

/* 图例样式 */
.map-legend {
    width: 120px;
    padding: 16px;
    background: #f8f9fa;
    border-left: 1px solid #e9ecef;
}

.legend-title {
    font-size: 12px;
    font-weight: 600;
    color: #666;
    margin-bottom: 12px;
    text-align: center;
}

.legend-items {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.legend-item {
    display: flex;
    align-items: center;
    gap: 8px;
}

.legend-color {
    width: 16px;
    height: 16px;
    border-radius: 2px;
    border: 1px solid #ddd;
}

.legend-label {
    font-size: 11px;
    color: #666;
    flex: 1;
}

/* 响应式设计 */
@media (max-width: 768px) {
    .map-content {
        flex-direction: column;
    }

    .map-legend {
        width: 100%;
        border-left: none;
        border-top: 1px solid #e9ecef;
    }

    .legend-items {
        flex-direction: row;
        flex-wrap: wrap;
        justify-content: center;
    }

    .legend-item {
        min-width: 80px;
    }

    .map-wrapper {
        padding: 10px;
    }
}

@media (max-width: 480px) {
    .map-header {
        flex-direction: column;
        gap: 12px;
        align-items: flex-start;
    }

    .map-controls {
        width: 100%;
        justify-content: flex-end;
    }
}
</style>
